package org.mat.framework.logging.operation.support;


import com.fasterxml.jackson.databind.ObjectMapper;
import org.mat.framework.logging.operation.api.ApiLog;
import org.mat.framework.logging.operation.api.OperateEnum;
import org.mat.framework.web.utils.IpUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.util.ContentCachingRequestWrapper;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * <p>Title: DefaultOperationLoggingExecutor </p>
 * <p>Date: 2020/4/23 </p>
 * <p>Description: 日志记录执行器（默认版本）</p>
 * 通过Slf4j记录操作日志
 *
 * @author sunxinhe
 */
@Slf4j
public class DefaultOperationLoggingExecutor implements OperationLoggingExecutor {

    @Override
    public void saveLog(HttpServletRequest httpServletRequest, ApiLog apiLog, Object[] args, LocalDateTime beginTime, String errorCode) {
        DefaultOperationLoggingDTO defaultOperationLoggingDTO = new DefaultOperationLoggingDTO();
        // 记录请求状态
        defaultOperationLoggingDTO.setOperateTime(beginTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
        if (StringUtils.isBlank(errorCode)) {
            defaultOperationLoggingDTO.setOperateResult("1");
        } else {
            defaultOperationLoggingDTO.setOperateResult("0");
        }

        // 记录请求用户
        String userId = httpServletRequest.getHeader("x-user-id");
        defaultOperationLoggingDTO.setUserId(userId);


        // 记录请求参数
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            OperationCondition operationCondition = new OperationCondition();
            operationCondition.setParameterMap(httpServletRequest.getParameterMap());
            String requestBody = new String(((ContentCachingRequestWrapper) httpServletRequest).getContentAsByteArray(), "UTF-8");
            operationCondition.setRequestBody(requestBody);
            String operationConditionJson = objectMapper.writeValueAsString(operationCondition);
            defaultOperationLoggingDTO.setOperateCondition(operationConditionJson);
        } catch (Exception exception) {
            log.error("获取请求参数发生异常", exception);
        }

        // 记录请求方IP地址
        defaultOperationLoggingDTO.setRequestIp(IpUtils.getIpAddrByRequest(httpServletRequest));

        // 记录操作类型、所属模块
        OperateEnum operateType = apiLog.operateType();
        defaultOperationLoggingDTO.setOperateType(operateType.getOperateType());
        defaultOperationLoggingDTO.setOperateName(operateType.getOperateName());
        defaultOperationLoggingDTO.setOperateModule(apiLog.operateModule());

        // 记录异常信息
        defaultOperationLoggingDTO.setErrorCode(errorCode);

        // 保存日志
        // TODO 输出到固定的logback文件
        log.info("defaultOperationLoggingDTO = {}", defaultOperationLoggingDTO);
    }
}
